Aspects
Aspects 是一个基于 Method Swizzle 的函数替换的第三方库,支持在方法执行前(AspectPositionBefore)/执行后(AspectPositionAfter)或替代原方法执行(AspectPositionInstead)
使用
HOOK一个类的所有实例的指定方法
1
2
3
4
5
6
7
8
9
10
11
12
13/// 为一个指定的类的某个方法执行前/替换/后,添加一段代码块.对这个类的所有对象都会起作用.
///
/// @param block 方法被添加钩子时,Aspectes会拷贝方法的签名信息.
/// 第一个参数将会是 `id<AspectInfo>`,余下的参数是此被调用的方法的参数.
/// 这些参数是可选的,并将被用于传递给block代码块对应位置的参数.
/// 你甚至使用一个没有任何参数或只有一个`id<AspectInfo>`参数的block代码块.
///
/// @注意 不支持给静态方法添加钩子.
/// @return 返回一个唯一值,用于取消此钩子.
+ (id<AspectToken>)aspect_hookSelector:(SEL)selector
withOptions:(AspectOptions)options
usingBlock:(id)block
error:(NSError **)error;HOOK一个类实例的指定方法
1
2
3
4
5/// 为一个指定的对象的某个方法执行前/替换/后,添加一段代码块.只作用于当前对象.
- (id<AspectToken>)aspect_hookSelector:(SEL)selector
withOptions:(AspectOptions)options
usingBlock:(id)block
error:(NSError **)error;Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27+(void)Aspect {
// 在类UIViewController所有的实例执行viewWillAppear:方法完毕后做一些事情
[UIViewController aspect_hookSelector:@selector(viewWillAppear:)
withOptions:AspectPositionAfter
usingBlock:^(id<AspectInfo> info) {
NSString *className = NSStringFromClass([[info instance] class]);
NSLog(@"%@", className);
} error:NULL];
// 在实例myVc执行viewWillAppear:方法完毕后做一些事情
UIViewController* myVc = [[UIViewController alloc] init];
[myVc aspect_hookSelector:@selector(viewWillAppear:)
withOptions:AspectPositionAfter
usingBlock:^(id<AspectInfo> info) {
id instance = info.instance; //调用的实例对象
id invocation = info.originalInvocation; //原始的方法
id arguments = info.arguments; //参数
[invocation invoke]; //原始的方法,再次调用
} error:NULL];
// HOOK类方法
Class metalClass = objc_getMetaClass(NSStringFromClass(UIViewController.class).UTF8String);
[metalClass aspect_hookSelector:@selector(ClassMethod)
withOptions:AspectPositionAfter
usingBlock:^(id<AspectInfo> info) {
NSLog(@"%@", HOOK类方法);
} error:NULL];
}